<template>
  <section class="flow-detail-container" v-loading="loading">
    <template v-if="!(flowInst && flowInst.id)">
      <div class="flow-empty-detail-box">
        <a-empty></a-empty>
      </div>
    </template>
    <template v-else>
      <div class="flow-status-stamp" v-if="!submitable">
        <FlowStatusStamp :status="filterStatus(flowInst)" :size="120" />
      </div>

      <!-- 基本信息 -->
      <div class="flow-header-box">
        <div class="flow-no">编号：{{ flowInst.id }}</div>
        <div class="action-area">
          <div class="action-item" @click="onPrintClicked()">
            <icon-printer :size="16" />
          </div>
          <!-- 打印 -->
          <FlowPrint
            v-model:visible="showPrintModal"
            :flow-inst="flowInst"
            :form-value="
              flowInst.formData?.data || flowInst?.flowInstance.formData?.data
            "
            :flow-nodes="flowNodes"
            :form-widgets="formWidgets"
          />
        </div>
      </div>
      <div class="flow-detail-box">
        <div class="header-box">
          <div class="summary-info">
            <div class="title">
              {{
                flowInst?.flowInstance?.createTime.slice(5, 10) ||
                flowInst.createTime.slice(5, 10)
              }}
              |
              {{ flowInst.flowInstance?.modelName ?? flowInst.modelName }}
            </div>
            <div class="status">
              <template v-if="!submitable">
                <a-tag color="blue" v-if="filterStatus(flowInst) == 0">
                  {{ TASK_STATUS[0].name }}
                </a-tag>
                <a-tag color="green" v-else-if="filterStatus(flowInst) == 1">
                  {{ TASK_STATUS[1].name }}
                </a-tag>
                <a-tag color="red" v-else-if="filterStatus(flowInst) == 2">
                  {{ TASK_STATUS[2].name }}
                </a-tag>
                <a-tag
                  color="orangered"
                  v-else-if="filterStatus(flowInst) == 3"
                >
                  {{ TASK_STATUS[3].name }}
                </a-tag>
              </template>
              <a-tag v-else-if="submitable"> 已保存 </a-tag>
            </div>
          </div>
          <div class="flow-info">
            <div class="group-name">
              {{ flowInst.flowInstance?.formName ?? flowInst.formName }}
            </div>
            <div class="inst-status">
              <a-badge
                :status="filterFlowStatus(flowInst).status"
                :text="'流程' + filterFlowStatus(flowInst).text"
              />
            </div>
          </div>
          <div class="initiator-info">
            <flow-node-avatar
              :size="24"
              :name="flowInst.flowInstance?.creatorName ?? flowInst.creatorName"
            />
            <div class="begin-time">
              {{ flowInst?.flowInstance?.createTime || flowInst.createTime }}
              提交
            </div>
          </div>
        </div>

        <!-- <a-divider orientation="left"> </a-divider> -->
        <!-- <div class="area-divider">
          <template v-if="formEditRecordBtnVisible">
            <div class="action-form-edit-btn" @click="onFormEditRecordClick()">
              <IconHistory :size="14" /> 编辑记录
            </div>
            <FormEditRecord
              v-model:visible="formEditRecordVisible"
              :form-widgets="formWidgets"
              :flowInstId="flowInst.id"
            />
          </template>
</div> -->

        <!-- 表单信息 -->
        <a-card style="margin: 20px 0">
          <form-iframe
            ref="formIframe"
            :flowInstId="flowInst.instanceId || flowInst.id"
            @getForm="onFormData"
          ></form-iframe>
        </a-card>

        <!-- <a-divider orientation="left"></a-divider> -->

        <!-- 审批流程时间线 -->
        <div class="flow-box" v-if="flowNodes && flowNodes.length > 0">
          <a-timeline mode="left" labelPosition="relative">
            <template v-for="(node, idx) in flowNodes" :key="idx">
              <a-timeline-item :label="node.operateTime">
                <template #dot>
                  <div class="assignee-container">
                    <!-- 进行中 -->
                    <template v-if="filterUnderway(node)">
                      <!-- 审批中 -->
                      <template v-if="node.nodeType == nodes[1]">
                        <a-avatar :size="36" style="background: #1989fa">
                          <icon-stamp :size="24" />
                        </a-avatar>
                      </template>
                      <!-- 办理中 -->
                      <template v-else-if="node.nodeType == nodes[5]">
                        <a-avatar :size="36" style="background: #926bd5">
                          <icon-pen-fill :size="24" />
                        </a-avatar>
                      </template>
                      <!-- 重新提交 -->
                      <template v-else-if="node.nodeType == nodes[0]">
                        <a-avatar :size="36" style="background: #1989fa">
                          <icon-edit :size="24" />
                        </a-avatar>
                      </template>
                      <!-- 抄送中 -->
                      <template v-else-if="node.nodeType == nodes[2]">
                        <a-avatar :size="36" style="background: #1989fa">
                          <svg-icon icon-class="copy" color="#fff" />
                        </a-avatar>
                      </template>
                      <!-- 等待图标 -->
                      <div class="badge">
                        <svg-icon icon-class="underway" color="#2a5eff" />
                      </div>
                    </template>
                    <!-- 已抄送 -->
                    <template v-else-if="node.nodeType == nodes[2]">
                      <a-avatar :size="36" style="background: #1989fa">
                        <svg-icon icon-class="copy" color="#fff" />
                      </a-avatar>
                      <div class="badge">
                        <svg-icon icon-class="approval" />
                      </div>
                    </template>
                    <!-- 已办理 -->
                    <!-- <template v-else-if="node.nodeType == nodes[5]">
                      <a-avatar :size="36" style="background: #926bd5">
                        <icon-pen-fill :size="24" />
                      </a-avatar>
                      <div class="badge">
                        <svg-icon icon-class="approval" />
                      </div>
                    </template> -->
                    <!-- 通过 -->
                    <template
                      v-else-if="
                        node.nodeType == nodes[1] && node.operateFlag == 1
                      "
                    >
                      <flow-node-avatar
                        :size="36"
                        :name="node.operatorName"
                        :show-name="false"
                      />
                      <div class="badge">
                        <svg-icon icon-class="approval" />
                      </div>
                    </template>
                    <!-- 拒绝 -->
                    <template
                      v-else-if="
                        node.nodeType == nodes[1] && node.operateFlag == 0
                      "
                    >
                      <flow-node-avatar
                        :size="36"
                        :name="node.operatorName"
                        :show-name="false"
                      />
                      <div class="badge"><svg-icon icon-class="reject" /></div>
                    </template>
                    <!-- 自动通过 -->
                    <template
                      v-else-if="[CMD.AUTO_APPROVED].includes(node.auto)"
                    >
                      <a-avatar :size="36" style="background: #1989fa">
                        <icon-robot />
                      </a-avatar>
                      <div class="badge">
                        <svg-icon icon-class="approval" />
                      </div>
                    </template>
                    <!-- 自动拒绝 -->
                    <template
                      v-else-if="[CMD.AUTO_REJECTED].includes(node.auto)"
                    >
                      <a-avatar :size="36" style="background: #1989fa">
                        <icon-robot />
                      </a-avatar>
                      <div class="badge"><svg-icon icon-class="reject" /></div>
                    </template>
                    <!-- 结束 -->
                    <template v-else>
                      <flow-node-avatar
                        :size="36"
                        :name="node.operatorName || '终'"
                        :show-name="false"
                      />
                      <div class="badge">
                        <svg-icon icon-class="approval" />
                      </div>
                    </template>
                  </div>
                </template>
                <div class="audit-record">
                  <div class="avatar sgement">
                    <div class="node-name">{{ node.nodeName }}</div>
                    <!-- 处理节点人信息 -->
                    <div class="auditor-name">
                      <template v-if="filterUnderway(node)">
                        <div class="node-sign-type">
                          <template v-if="node.multiType == MULTI_TYPE[2]">
                            <template v-if="node.nodeType == nodes[1]">
                              只需一人审批同意
                            </template>
                            <template v-if="node.nodeType == nodes[5]">
                              只需一人办理同意
                            </template>
                          </template>
                          <template
                            v-else-if="
                              filterUsers(node.operatorName).length > 1
                            "
                          >
                            <template v-if="node.type == nodes[1]">
                              需所有人审批同意
                            </template>
                            <template v-if="node.type == nodes[5]">
                              需所有人办理同意
                            </template>
                          </template>
                        </div>
                        <div class="node-assignee">
                          <flow-node-avatar
                            v-for="(userName, idx) in filterUsers(
                              node.operatorName
                            )"
                            :key="idx"
                            :size="20"
                            :name="userName"
                            class="assignee-item"
                          />
                          <!-- <flow-node-role-avatar
                            v-for="roleId in node.roleIds"
                            :size="20"
                            :id="roleId"
                            class="assignee-item"
                          /> -->
                        </div>
                      </template>
                      <template v-else>
                        <template v-if="node.flowCmd == CMD.COPY">
                          <!-- <div class="node-sign-assignee">抄送{{ node.userIds.length }}人</div> -->
                          <div
                            v-if="node.flowCmd == CMD.COPY"
                            class="node-assignee"
                          >
                            <flow-node-avatar
                              v-for="userId in node.userIds"
                              :key="userId"
                              :size="20"
                              :id="userId"
                              class="assignee-item"
                            />
                          </div>
                        </template>
                        <template v-else>
                          <div class="assignee-name">
                            {{ node.operatorName }}
                          </div>
                          <div class="node-sign-assignee">
                            <template
                              v-if="[CMD.ASSIGN].includes(node.flowCmd)"
                            >
                              转交给
                              <div class="node-sign-assignee-name">
                                {{
                                  ArrayUtil.get(users, "id", node.assignee).name
                                }}
                              </div>
                            </template>
                          </div>
                        </template>
                      </template>
                    </div>
                    <div class="comment" v-if="node.comment">
                      <!-- <div class="commnet-title">审批意见</div> -->
                      <div class="comment-content">
                        {{ node.comment }}
                      </div>
                      <!-- 图片 -->
                      <!-- <div class="comment-attachment" v-if="node.files">
                        <div
                          class="comment-attachment-item"
                          v-for="(attachment, idx) in node.files"
                          :key="idx"
                        >
                          <div class="name">
                            <icon-drive-file :size="16" />
                            {{ attachment ? attachment.name : "" }}
                          </div>
                          <div class="download-icon">
                            <div
                              class="link"
                              @click.prevent.stop="
                                onAttachmentDownload(attachment, $event)
                              "
                            >
                              <icon-download :size="16" />
                            </div>
                          </div>
                        </div>
                      </div> -->
                    </div>
                  </div>
                </div>
              </a-timeline-item>
            </template>
          </a-timeline>
        </div>
      </div>

      <!-- 底部操作栏 -->
      <div class="flow-actions">
        <template
          v-if="
            !finished && flowInst.nodeSignType == 0 && editable && formEditable
          "
        >
          <a-tooltip content="编辑审批表单" mini>
            <a-button @click="onFormEdit()">
              <template #icon><icon-edit /></template> 编辑
            </a-button>
          </a-tooltip>
          <FormEdit
            :form-value="formValue"
            :flow-inst="flowInst"
            :form-widgets="formWidgets"
            v-model:visible="formEditVisible"
            @onOk="onFormUpdated"
          />
        </template>

        <!-- <template v-if="commentable">
          <a-button @click="onComment()">
            <template #icon><icon-message /></template> 评论
          </a-button>
        </template> -->

        <template v-if="submitable">
          <a-button type="primary" status="success" @click="onStart()">
            <template #icon><icon-arrow-rise /></template> 提 交
          </a-button>
        </template>

        <!-- 抄送查看 -->
        <template
          v-if="actionable && copyable && flowInst?.taskStatus == 'TODO'"
        >
          <a-button type="primary" status="success" @click="onCopyed()">
            <template #icon><icon-eye /></template> 已查看
          </a-button>
        </template>

        <template
          v-if="
            flowInst.buttonAuth &&
            ObjectUtil.isObject(flowInst.buttonAuth) &&
            !finished &&
            actionable
          "
        >
          <template v-if="flowInst.buttonAuth.agree">
            <a-button type="primary" status="success" @click="onApproved()">
              <template #icon><icon-check /></template> 同意
            </a-button>
          </template>
          <template v-if="flowInst.buttonAuth.reject">
            <a-button type="primary" status="danger" @click="onRejected()">
              <template #icon><icon-close /></template> 拒绝
            </a-button>
          </template>

          <template
            v-if="flowInst.buttonAuth.submit && !finished && actionable"
          >
            <a-button
              type="primary"
              @click="onTransacted()"
              v-if="flowInst.nodeType == 'USER_TASK'"
            >
              <template #icon><icon-check /></template> 提交
            </a-button>
            <a-button type="primary" @click="onSubmit()" v-else>
              <template #icon><icon-check /></template> 提交
            </a-button>
          </template>
        </template>
        <template
          v-if="
            flowInst.buttonAuth?.revoke && !finished && cancelable && canceled
          "
        >
          <a-button @click="onCanceled()">
            <template #icon><icon-undo /></template> 撤回
          </a-button>
        </template>

        <a-dropdown
          :popup-max-height="false"
          v-if="
            !finished &&
            actionable &&
            (isTransfer() || flowInst.buttonAuth?.back)
          "
          class="flow-actions-box"
        >
          <a-button>
            <template #icon><icon-down /></template> 更多
          </a-button>
          <template #content>
            <a-doption @click="onAssigned()" v-if="isTransfer()">
              <template #icon><icon-swap /></template>
              <template #default>
                <div class="action-name">转交</div>
              </template>
            </a-doption>
            <a-doption @click="onJumped()" v-if="flowInst.buttonAuth?.back">
              <template #icon><icon-backward /></template>
              <template #default>
                <div class="action-name">回退</div>
              </template>
            </a-doption>
          </template>
        </a-dropdown>
      </div>
    </template>

    <!-- 处理流程的弹窗 -->
    <a-modal
      :visible="showHandleModal"
      @ok="onHandleModelOK"
      @cancel="onHandleModelCancel"
      draggable
    >
      <template #title> {{ handleModalTitle }} </template>
      <div class="flow-exe-box">
        <a-form :model="handleModalForm" layout="vertical">
          <template v-if="handleModalForm.flowCmd == CMD.ASSIGN">
            <!-- <div class="action-tip">将当前审批转交给其他人审批，自己无需再审批。例如不方便处理当前审批时，可以转交给其他人。</div> -->
            <a-form-item
              field="targetUserId"
              label="转交给"
              :required="handleModalForm.flowCmd == CMD.ASSIGN"
            >
              <a-select
                v-model:model-value="handleModalForm.targetUserId"
                allow-search
                placeholder="请选择转交人员"
              >
                <a-option
                  v-for="user in users"
                  :key="user.id"
                  :value="user.id"
                  :label="user.name"
                />
              </a-select>
            </a-form-item>
          </template>

          <template v-if="handleModalForm.flowCmd == CMD.BACK">
            <!-- <div class="action-tip">将流程回退到之前某一节点重新审批。例如发现之前审批有误时，可以将流程回退到该节点。</div> -->
            <a-form-item
              field="targetNodeId"
              label="回退到"
              :required="handleModalForm.flowCmd == CMD.BACK"
            >
              <a-select
                v-model:model-value="handleModalForm.targetNodeId"
                allow-search
                placeholder="请选择回退节点"
              >
                <a-option
                  v-for="node in filterNodes"
                  :key="node.id"
                  :value="node.id"
                  :label="node.nodeName"
                  :disabled="node.disabled"
                />
              </a-select>
            </a-form-item>
          </template>

          <a-form-item
            field="comment"
            :label="handleModelCommentLabel(handleModalForm.flowCmd)"
            :required="
              handleModalForm.flowCmd == CMD.COMMENT ||
              handleModalForm.flowCmd == CMD.REJECTED
            "
          >
            <a-textarea
              v-model:model-value="handleModalForm.comment"
              :placeholder="`请输入${handleModelCommentLabel(
                handleModalForm.flowCmd
              )}`"
              allow-clear
              :max-length="64"
              show-word-limit
            />
          </a-form-item>

          <!-- <a-form-item field="fileIds" label="附件">
            <a-upload
              v-model:file-list="handleModalForm.fileIds"
              :action="fileUploadUrl"
              :headers="fileUploadHeaders"
              :with-credentials="true"
              multiple
              :limit="3"
              class="action-attachment"
            >
              <template #upload-button>
                <a-button>
                  <template #icon><icon-attachment /></template>上传
                </a-button>
              </template>
            </a-upload>
          </a-form-item> -->
        </a-form>
      </div>
    </a-modal>
  </section>
</template>

<script setup>
import { computed, onMounted, ref, watch } from "vue";
import { useOrganStore } from "@/stores";
import { getToken } from "@/utils/auth";
import ArrayUtil from "@/components/flow/common/ArrayUtil";
import ObjectUtil from "@/components/flow/common/ObjectUtil";
import {
  CMD,
  NODE,
  NODE_TYPE,
  NODE_SIGN,
  STATUS,
  TASK_STATUS,
  INSTANCE_STATUS,
  WIDGET,
  filterStatus,
  MULTI_TYPE,
} from "@/components/flow/common/FlowConstant";
import { FILE_BASE_URL } from "@/api/FileApi";
import FlowInstApi from "@/api/FlowInstApi";
import FlowManApi from "@/api/FlowManApi";
import OrganApi from "@/api/OrganApi";
import FlowNodeAvatar from "@/components/common/FlowNodeAvatar.vue";
import FlowNodeRoleAvatar from "@/components/common/FlowNodeRoleAvatar.vue";
import FlowPrint from "./flow-print.vue";
import FlowStatusStamp from "./flow-status-stamp.vue";
import FormEditRecord from "./form-edit-record.vue";
import FormEdit from "./form-edit.vue";
import FormIframe from "./form-iframe.vue";
import {
  IconAttachment,
  IconBackward,
  IconCheck,
  IconClose,
  IconDown,
  IconDownload,
  IconDriveFile,
  IconEdit,
  IconHistory,
  IconMessage,
  IconPenFill,
  IconPrinter,
  IconQuestionCircle,
  IconRobot,
  IconStamp,
  IconSwap,
  IconUndo,
  IconUserAdd,
  IconRedo,
  IconEye,
  IconArrowRise,
} from "@arco-design/web-vue/es/icon";
import { Modal, Notification } from "@arco-design/web-vue";

let organStore = useOrganStore();
let users = computed(() => organStore.users);

let props = defineProps({
  flowInst: { type: Object, default: () => {} },
  cancelable: { type: Boolean, default: false }, // 撤回按钮
  commentable: { type: Boolean, default: true }, //评论按钮
  actionable: { type: Boolean, default: false }, // 其他操作按钮
  editable: { type: Boolean, default: false }, // 表单是否可以编辑
  copyable: { type: Boolean, default: false }, // 抄送
  submitable: { type: Boolean, default: false }, // 保存待提交
});
let emits = defineEmits(["onRemove", "update:flowInst"]);

let fileUploadUrl = FILE_BASE_URL + "/upload"; //文件上传地址
let fileUploadHeaders = ref({ Authorization: getToken() }); // 文件上传请求头
const loading = ref(false);
let formWidgets = ref([]);
let formWidgetMap = ref({});
let flowNodes = ref([]);
let formValue = ref({});

let finished = computed(
  () =>
    (props.flowInst.instanceStatus ||
      props.flowInst.flowInstance.instanceStatus) == "FINISH"
);

let canceled = computed(
  () =>
    (props.flowInst.instanceStatus ||
      props.flowInst.flowInstance.instanceStatus) != "REVOKE"
);

// 节点list
let nodes = Object.keys(NODE_TYPE);

// 是否处于审核中
const filterUnderway = (node) => {
  return node.taskStatus == "TODO";
};

// 是否可以转交
const isTransfer = () => {
  return (
    props.flowInst.taskType != "TRANSFER" && props.flowInst.buttonAuth?.turn
  );
};

// 查询表单组件
const loadFormWidgets = () => {
  return FlowInstApi.getForm({
    id: props.flowInst.modelId,
  }).then((resp) => {
    if (resp.code == 0) {
      let form = resp.data || {};
      let widgets = JSON.parse(form.flowWidgets);
      // let values = form.formValue;
      formWidgets.value = widgets;
      // formValue.value = JSON.parse(values);
    }
  });
};

const filterFlowStatus = (inst) => {
  return INSTANCE_STATUS[
    inst.flowInstance?.instanceStatus || inst.instanceStatus
  ];
};

// 用户角色
const filterUsers = (string) => {
  const users = string?.split(",")?.map((user) => {
    return user;
  });
  return users;
};

// 获取审批节点 时间线
const loadFlowDetail = () => {
  // getInsthistory
  loading.value = true;
  FlowInstApi.getInsthistory({
    instanceId: props.flowInst.instanceId || props.flowInst.id,
  })
    .then((resp) => {
      loading.value = false;
      if (resp.code == 0) {
        flowNodes.value = resp.data?.records || [];
      }
    })
    .catch(() => (loading.value = false));
};

// 附件下载
const onAttachmentDownload = (attachment, evt) => {
  evt.stopPropagation();
  window.open(FILE_BASE_URL + "/download?id=" + attachment.id, "_blank");
};

// 打印相关
let showPrintModal = ref(false);
const onPrintClicked = () => {
  showPrintModal.value = true;
};

// 处理流程弹窗相关
let jumpableNodes = ref([]);
let filterNodes = computed(() => {
  const nodes = jumpableNodes.value.map((node, index) => {
    if (node.id == props.flowInst.nodeId) {
      jumpableNodes.value.slice(index).map((item) => {
        item.disabled = true;
        return item;
      });
    }
    return node;
  });
  return nodes;
});

let deleteableUserIds = ref([]);
let showHandleModal = ref(false);
let handleModalTitle = ref("");
let handleModalForm = ref({});
let formData = ref({});

const onHandleModelCancel = () => {
  showHandleModal.value = false;
  handleModalTitle.value = "";
  handleModalForm.value = {
    insId: null, // 流程实例id
    taskId: null, // 任务id
    flowCmd: null, // 任务指令
    operateFlag: null, //审批指令
    formData: null, //表单数据
    assignee: null, //指派人
    comment: null, //备注
    operateType: null,
  };
};

// 处理流程弹窗表单评论label
const handleModelCommentLabel = (cmd) => {
  switch (cmd) {
    case CMD.APPROVED:
    case CMD.REJECTED:
    case CMD.ASSIGN:
    case CMD.ADD_BEFORE_SIGN:
    case CMD.ADD_AFTER_SIGN:
    case CMD.ADD_SIGN:
    case CMD.DEL_SIGN:
      return "审批意见";
    case CMD.CANCELED:
      return "撤回理由";
    case CMD.COPY:
      return "抄送意见";
    case CMD.BACK:
      return "回退原因";
    case CMD.COMMENT:
      return "评论";
    case CMD.TRANSACT:
      return "办理意见";
    case CMD.SUBMIT:
      return "提交意见";
  }
};

const onHandleModelOK = () => {
  // 取出上传的文件id
  let handleModalFormValue = ObjectUtil.copy(handleModalForm.value);
  console.log("onHandleModelOK", handleModalFormValue);
  // insId operateFlag comment formData taskId
  let { flowCmd: cmd, fileIds } = handleModalFormValue;
  if (fileIds && fileIds.length > 0)
    handleModalFormValue.fileIds = fileIds.map(
      (v) => (v.response || {}).data.id
    );
  let req = null;
  switch (cmd) {
    case CMD.CANCELED:
      req = FlowInstApi.cancel(handleModalFormValue);
      break;
    case CMD.COMMENT:
      req = FlowInstApi.comment(handleModalFormValue);
      break;
    case CMD.BACK:
      req = FlowInstApi.jump(handleModalFormValue);
      break;
    case CMD.ADD_BEFORE_SIGN:
      req = FlowInstApi.addBeforeSign(handleModalFormValue);
      break;
    case CMD.ADD_AFTER_SIGN:
      req = FlowInstApi.addAfterSign(handleModalFormValue);
      break;
    case CMD.ADD_SIGN:
      req = FlowInstApi.addSign(handleModalFormValue);
      break;
    case CMD.DEL_SIGN:
      req = FlowInstApi.delSign(handleModalFormValue);
      break;
    case CMD.APPROVED:
      req =
        props.flowInst.taskType == "TRANSFER"
          ? FlowInstApi.recieve(handleModalFormValue)
          : FlowInstApi.approve(handleModalFormValue);
      break;
    case CMD.REJECTED:
      req =
        props.flowInst.taskType == "TRANSFER"
          ? FlowInstApi.recieve(handleModalFormValue)
          : FlowInstApi.reject(handleModalFormValue);
      break;
    case CMD.COPY:
      req = FlowInstApi.copy(handleModalFormValue);
      break;
    case CMD.ASSIGN:
      req = FlowInstApi.assign(handleModalFormValue);
      break;
    case CMD.TRANSACT:
      req = FlowInstApi.transact(handleModalFormValue);
      break;
    case CMD.SUBMIT:
      req = FlowInstApi.submit(handleModalFormValue);
      break;
    case CMD.START:
      req = FlowInstApi.flowStart({
        operateType: "START",
        modelId: props.flowInst.modelId,
        instanceId: props.flowInst.instanceId,
        modelKey: props.flowInst.modelKey,
        formData: handleModalFormValue.formData,
        variable: props.flowInst.variable || {},
      });
      break;
  }
  req.then((resp) => {
    if (resp.code == 0) {
      onHandleModelCancel();
      if (cmd == CMD.CANCELED) {
        if (props.flowInst.flowInstance) {
          props.flowInst.flowInstance.instanceStatus = TASK_STATUS[3].value;
        } else {
          props.flowInst.instanceStatus = TASK_STATUS[3].value;
        }
        emits("update:flowInst", props.flowInst);
      }
      if (
        [
          CMD.ASSIGN,
          CMD.BACK,
          CMD.ADD_BEFORE_SIGN,
          CMD.ADD_AFTER_SIGN,
          CMD.APPROVED,
          CMD.REJECTED,
          CMD.TRANSACT,
          CMD.COPY,
          CMD.SUBMIT,
          CMD.START,
        ].includes(cmd)
      ) {
        emits("onRemove");
      } else {
        loadFlowDetail();
      }
    }
  });
};
const formIframe = ref();
const initModalForm = (cmd) => {
  if (formIframe.value) {
    formIframe.value.sendIframeData("get");
  }
  console.log("initModalForm", cmd);
  const FLAG = {
    4: 1,
    3: 0,
  };
  return {
    insId: props.flowInst?.flowInstance.id || props.flowInst.instanceId,
    taskId: props.flowInst.id,
    operateFlag: FLAG[cmd],
    formData: props.flowInst.formData,
    flowCmd: cmd,
    operateType: "HANDLE",
  };
};
// 获取表单数据
const onFormData = (data) => {
  return new Promise((resolve, reject) => {
    console.log("onFormData", data);
    if (data) {
      handleModalForm.value.formData = data;
      resolve(data);
    }
  });
};
const onApproved = () => {
  if (props.flowInst.taskType == "TRANSFER") {
    handleModalTitle.value = "接收转交任务";
    handleModalForm.value = initModalForm(CMD.APPROVED);
  } else {
    handleModalTitle.value = "同意审批";
    handleModalForm.value = initModalForm(CMD.APPROVED);
  }
  showHandleModal.value = true;
};
const onRejected = () => {
  if (props.flowInst.taskType == "TRANSFER") {
    handleModalTitle.value = "拒绝转交任务";
    handleModalForm.value = initModalForm(CMD.REJECTED);
  } else {
    handleModalTitle.value = "拒绝审批";
    handleModalForm.value = initModalForm(CMD.REJECTED);
  }
  showHandleModal.value = true;
};
// 抄送
const onCopyed = () => {
  handleModalTitle.value = "查看抄送";
  handleModalForm.value = initModalForm(CMD.COPY);
  showHandleModal.value = true;
};
const onTransacted = () => {
  handleModalTitle.value = "审批办理";
  handleModalForm.value = initModalForm(CMD.TRANSACT);
  showHandleModal.value = true;
};
// 提交
const onSubmit = async () => {
  handleModalTitle.value = "提交意见";
  handleModalForm.value = initModalForm(CMD.SUBMIT);
  showHandleModal.value = true;
};
const onCanceled = () => {
  handleModalTitle.value = "撤回审批";
  handleModalForm.value = initModalForm(CMD.CANCELED);
  showHandleModal.value = true;
};
const onAssigned = () => {
  handleModalTitle.value = "转交审批";
  handleModalForm.value = initModalForm(CMD.ASSIGN);
  showHandleModal.value = true;
};
const onComment = () => {
  handleModalTitle.value = "评论审批";
  handleModalForm.value = initModalForm(CMD.COMMENT);
  showHandleModal.value = true;
};
const onStart = () => {
  handleModalTitle.value = "发起流程";
  handleModalForm.value = initModalForm(CMD.START);
  // showHandleModal.value = true;
  Modal.confirm({
    title: "确认发起该草稿？",
    // content: "您确认发起该流程？",
    onOk: () => {
      onHandleModelOK();
    },
  });
};
const onJumped = () => {
  FlowInstApi.listJumpableNodes({
    modelId: props.flowInst.modelId,
  }).then((resp) => {
    if (resp.code == 0) jumpableNodes.value = resp.data.records || [];
  });
  handleModalTitle.value = "回退审批";
  handleModalForm.value = initModalForm(CMD.BACK);
  showHandleModal.value = true;
};
const onAddSigned = () => {
  handleModalTitle.value = "审批加签";
  handleModalForm.value = initModalForm(CMD.ADD_SIGN);
  showHandleModal.value = true;
};
const onDelSigned = () => {
  FlowInstApi.listRemoveableNodeAssignees({
    flowInstId: props.flowInst.id,
    actNodeId: props.flowInst.actNodeId,
  }).then((resp) => {
    if (resp.code == 1) deleteableUserIds.value = resp.data || [];
  });
  handleModalTitle.value = "审批减签";
  handleModalForm.value = initModalForm(CMD.DEL_SIGN);
  showHandleModal.value = true;
};

// 是否显示编辑记录按钮
const formEditRecordBtnVisible = ref(false);
const hasFormEditRecord = () => {
  FlowInstApi.hasFormEditRecord({ flowInstId: props.flowInst.id }).then(
    (resp) => {
      if (resp.code == 1) formEditRecordBtnVisible.value = resp.data;
    }
  );
};

// 表单编辑相关
const formEditVisible = ref(false);
const formEditRecordVisible = ref(false);
const formEditable = computed(() => {
  let tmp = false;
  formWidgets.value.forEach((formWidget) => {
    if (formWidget.type == WIDGET.DETAIL) {
      formWidget.details.forEach((detail) => {
        if (detail.editable) tmp = true;
      });
    } else if (formWidget.editable) tmp = true;
  });
  return tmp;
});
const onFormEdit = () => {
  formEditVisible.value = true;
};
const onFormUpdated = (nv) => {
  formValue.value = JSON.parse(nv);
  hasFormEditRecord();
};
const onFormEditRecordClick = () => {
  formEditRecordVisible.value = true;
};

watch(
  () => props.flowInst,
  (nv) => {
    if (nv && nv.id && nv.modelId) {
      loadFlowDetail();
      loadFormWidgets();
      // hasFormEditRecord();
    }
  },
  { immediate: true }
);

onMounted(() => {
  OrganApi.loadOrgan(); // 加载组织
});
</script>

<style lang="less" scoped>
@import "@/styles/variables.module.less";
@bottomActionHeight: 52px;
@DetailHeaderHeight: 40px;
@FormLabelWidth: 84px;

.flow-detail-container {
  height: 100%;
  overflow: hidden;
  position: relative;
}

.flow-empty-detail-box {
  margin-top: 20%;
}

.flow-status-stamp {
  position: absolute;
  right: 30px;
  top: 30px;
}

.area-divider {
  border-bottom: 1px solid var(--color-neutral-3);
  margin: 20px 0;
  position: relative;
}

.action-form-edit-btn {
  user-select: none;
  position: absolute;
  right: 0;
  top: 0;
  border: 1px solid var(--color-neutral-3);
  border-top: 0;
  border-radius: 0 0 4px 4px;
  cursor: pointer;
  padding: 4px;
  font-size: 12px;
  color: #86909c;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 2px;

  &:hover {
    background-color: #f2f3f5;
  }
}

.flow-header-box {
  font-weight: 400;
  font-size: 13px;
  border-bottom: 1px solid #e5e6ec;
  padding: 0 @GapLarge;
  height: calc(@DetailHeaderHeight - 1px);
  display: flex;
  align-items: center;
  justify-content: space-between;
  color: #86909c;

  .action-area {
    display: flex;
    gap: 4px;

    .action-item {
      cursor: pointer;
      padding: 4px;
      border-radius: @BorderRadius;
      width: fit-content;
      height: fit-content;

      &:hover {
        background-color: #f2f3f5;
      }
    }
  }
}

.flow-detail-box {
  height: calc(100% - @bottomActionHeight - @DetailHeaderHeight);
  overflow: hidden;
  overflow-y: auto;
  padding: 0 calc(@GapLarge + 10px);

  .header-box {
    display: flex;
    flex-direction: column;
    justify-content: center;
    padding-top: 20px;

    .summary-info {
      display: flex;
      align-items: center;

      .title {
        font-size: 24px;
        font-family: PingFangSC-Semibold, PingFang SC;
        color: #1d2129;
      }

      .status {
        margin-left: 20px;
      }
    }

    .flow-info {
      margin-top: 16px;
      font-size: 14px;
      display: flex;
      align-items: center;

      .inst-status {
        margin-left: 20px;
      }
    }

    .initiator-info {
      display: flex;
      align-items: center;
      margin-top: 16px;

      .begin-time {
        margin-left: 20px;
        font-weight: 350;
        color: #86909c;
        font-size: 13px;
        user-select: none;
      }
    }
  }

  // 流程时间线相关样式
  .flow-box {
    user-select: none;

    // 流程头像
    .assignee-container {
      position: relative;

      .badge {
        @BadgeSize: 18px;
        @BadgeOffset: -4px;
        position: absolute;
        width: @BadgeSize;
        height: @BadgeSize;
        display: flex;
        align-items: center;
        justify-content: center;
        bottom: @BadgeOffset;
        right: @BadgeOffset;
        z-index: 999;
        border: 2px solid #fff;
        background-color: #fff;
        border-radius: 50%;
        overflow: hidden;
      }
    }

    .audit-record {
      display: flex;
      flex-direction: row;
      justify-content: space-between;

      .sgement {
        margin-left: 8px;
        flex: 1;
      }

      .node-name {
        font-weight: 400;
        color: #86909c;

        .in-approval {
          color: #2a5eff;
        }
      }

      .auditor-name {
        font-size: 14px;

        .node-sign-type,
        .node-sign-assignee {
          font-weight: 400;
          color: #86909c;
          font-size: 12px;

          .node-sign-assignee-name {
            color: #2a5eff;
            display: inline-block;
          }
        }

        .node-assignee {
          margin-top: 4px;
          display: flex;
          flex-flow: row wrap;
          gap: 6px;
        }

        .assignee-name {
          color: #1d2129;
        }
      }

      .comment {
        user-select: none;
        margin: 4px 0 16px;
        padding: 8px 16px;
        border-radius: 4px;
        background-color: #f8f8fa;

        .commnet-title {
          font-weight: 400;
          color: #a6aab1;
          font-size: 13px;
        }

        .comment-content {
          font-weight: 500;
          color: #1d2129;
        }

        .comment-attachment {
          gap: 10px;
          margin: 4px 0;
          display: flex;
          flex-wrap: wrap;

          .comment-attachment-item {
            border-radius: 4px;
            border: 1px solid #e1e1e1;
            padding: 4px 8px;
            display: flex;
            align-items: center;
            justify-content: space-between;
            gap: 10px;

            .name {
              display: flex;
              align-items: center;
              gap: 4px;
            }

            .download-icon {
              display: flex;
              align-items: center;
              cursor: pointer;
              color: #165cfd;

              &:hover {
                opacity: 0.7;
              }
            }
          }
        }
      }

      .cmd {
        text-align: right;
      }
    }
  }
}

.flow-actions {
  display: flex;
  align-items: center;
  justify-content: end;
  height: @bottomActionHeight;
  border-top: 1px solid var(--color-neutral-3);
  padding: 0 @GapLarge;

  button {
    + button {
      margin-left: 10px;
    }
  }
}
</style>

<style lang="less">
.flow-detail-box {
  .arco-timeline-item {
    min-height: 108px;
  }

  .arco-timeline-item-dot-line {
    top: 40px;
    bottom: 4px;
    border-color: #bed0f7;
    border-left-width: 2px;
  }

  .arco-timeline-item-dot-content {
    width: 36px;
    height: 36px;
    line-height: 36px;
  }

  .arco-timeline-item-content-wrapper {
    margin-left: 36px;
  }

  .arco-table-cell {
    padding: 6px;
    font-size: 13px;
    min-height: 30px;
  }
}

.arco-image-preview {
  .arco-image-preview-arrow {
    position: initial;
  }
}

.arco-dropdown-open .arco-icon-down {
  transform: rotate(180deg);
}

.flow-actions-box {
  .arco-dropdown {
    padding: 4px;
  }
}

.flow-exe-box {
  .modify-sign-group {
    display: grid;
    grid-template-columns: 1fr 1fr 1fr;
    width: 100%;

    .modify-sign-tip {
      color: var(--color-text-4);
    }
  }

  .action-attachment {
    .arco-upload-list-item {
      margin-top: 0;

      &:first-of-type {
        margin-top: 12px;
      }

      .arco-upload-list-item-content {
        padding: 4px 10px 4px 12px;
      }

      .arco-upload-list-item-operation {
        .arco-icon {
          font-size: 16px;
        }
      }
    }

    .arco-upload-hide + .arco-upload-list .arco-upload-list-item:first-of-type {
      margin-top: 0px;
    }
  }
}
</style>
